using PF;
using System;

namespace ETModel
{
    [ObjectSystem]
    public class PathfindingComponentAwakeSystem : AwakeSystem<PathfindingComponent, string>
    {
        public override void Awake(PathfindingComponent self, string graphFilePath)
        {
            self.PathReturnQueue = new PathReturnQueue(self);
            self.PathProcessor = new PathProcessor(self.PathReturnQueue, 1, false);
            
            // 读取寻路配置
            self.AStarConfig = new AStarConfig();
            self.AStarConfig.pathProcessor = self.PathProcessor;
            
            // 读取地图数据
            self.AStarConfig.graphs = DeserializeHelper.Load(graphFilePath);
        }
    }

    /// <summary>
    /// 寻路组件,可附加在全局场景上,或者(自定义的)"地形"对象上进行区分地图寻路<para/>
    /// AddComponent&lt;PathfindingComponent, string&gt;(graphFilePath)
    /// </summary>
    public class PathfindingComponent: Component
    {
        public PathReturnQueue PathReturnQueue;
        
        public PathProcessor PathProcessor;

        public AStarConfig AStarConfig;

        public bool Search(ABPathWrap path)
        {
            if (AStarConfig.graphs == null) {
                throw new Exception("寻路组件未初始化寻路数据,可使用这种附加组件方式:AddComponent<PathfindingComponent, string>(graphFilePath); 也可以单独操作AStarConfig.graphs");
            }

            PathProcessor.queue.Push(path.Path);
            while (this.PathProcessor.CalculatePaths().MoveNext())
            {
                if (path.Path.CompleteState != PathCompleteState.NotCalculated)
                {
                    break;
                }
            }

            if (path.Path.CompleteState != PathCompleteState.Complete)
            {
                return false;
            }
            
            PathModifyHelper.StartEndModify(path.Path);
            PathModifyHelper.FunnelModify(path.Path);

            return true;
        }

        public override void Dispose() {
            if (IsDisposed) return;
            base.Dispose();
            try {
                PathProcessor?.AbortThreads();
            } catch { }
            try {
                AStarConfig?.pathProcessor?.AbortThreads();
            } catch { }
            AStarConfig?.Dispose();
            PathReturnQueue = null;
        }
    }
}